/*
 * Copyright Aduna (http://www.aduna-software.com/) (c) 2009.
 *
 * Licensed under the Aduna BSD-style license.
 */

package edu.tju.commons.collections.iterators;

import java.util.concurrent.atomic.AtomicBoolean;

/**
 * Base class for {@link CloseableIterator}s offering common functionality. This
 * class keeps track of whether the iterator has been closed and handles
 * multiple calls to {@link #close()} by ignoring all but the first call.
 */
public abstract class CloseableIteratorBase<E> implements CloseableIterator<E> {

	/**
	 * Flag indicating whether this iterator has been closed.
	 */
	private final AtomicBoolean closed = new AtomicBoolean(false);

	/**
	 * Checks whether this iterator has been closed.
	 * 
	 * @return <tt>true</tt> if the iterator has been closed, <tt>false</tt>
	 *         otherwise.
	 */
	public final boolean isClosed() {
		return closed.get();
	}

	/**
	 * Calls {@link #handleClose()} upon first call and makes sure this method
	 * gets called only once.
	 */
	public final void close() {
		if (closed.compareAndSet(false, true)) {
			handleClose();
		}
	}

	/**
	 * Called by {@link #close} when it is called for the first time. This method
	 * is only called once on each iteration. By default, this method does
	 * nothing.
	 */
	protected void handleClose() {
	}
}
